home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termTransfer.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  57KB  |  2,743 lines

  1. /*
  2. **    termTransfer.c
  3. **
  4. **    File transfer routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* The action strings to display. */
  13.  
  14. STATIC STRPTR    SendQuery[3],
  15.         ReceiveQuery[3],
  16.         TransferTypes[3];
  17.  
  18.     /* CreateArgName(STRPTR String):
  19.      *
  20.      *    Create another node based upon a string given.
  21.      *    Encloses parameters in quotes if necessary and
  22.      *    `escapes' quotes.
  23.      */
  24.  
  25. STATIC struct Node * __regargs
  26. CreateArgName(STRPTR String)
  27. {
  28.     struct Node    *Node;
  29.     STRPTR         Index = String;
  30.     LONG         Len,NewLen;
  31.     BOOLEAN         Quotes = FALSE;
  32.  
  33.     Len = NewLen = strlen(String);
  34.  
  35.     while(*Index)
  36.     {
  37.         if(*Index == '\"')
  38.             NewLen++;
  39.  
  40.         if(*Index == ' ' && !Quotes)
  41.         {
  42.             NewLen += 2;
  43.  
  44.             Quotes = TRUE;
  45.         }
  46.  
  47.         Index++;
  48.     }
  49.  
  50.     if(!Len)
  51.     {
  52.         NewLen += 2;
  53.  
  54.         Quotes = TRUE;
  55.     }
  56.  
  57.     if(NewLen > Len)
  58.     {
  59.         if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + NewLen + 1,MEMF_ANY))
  60.         {
  61.             STRPTR Dest;
  62.  
  63.             Node -> ln_Name = (STRPTR)(Node + 1);
  64.  
  65.             Dest    = Node -> ln_Name;
  66.             Index    = String;
  67.  
  68.             if(Quotes)
  69.                 *Dest++ = '\"';
  70.  
  71.             while(*Index)
  72.             {
  73.                 if(*Index == '\"')
  74.                     *Dest++ = '*';
  75.  
  76.                 *Dest++ = *Index++;
  77.             }
  78.  
  79.             if(Quotes)
  80.                 *Dest++ = '\"';
  81.  
  82.             *Dest = 0;
  83.         }
  84.     }
  85.     else
  86.     {
  87.         if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + Len + 1,MEMF_ANY))
  88.             strcpy(Node -> ln_Name = (STRPTR)(Node + 1),String);
  89.     }
  90.  
  91.     return(Node);
  92. }
  93.  
  94.     /* BuildString():
  95.      *
  96.      *    Build a command line based upon a template and
  97.      *    existing file transfer info.
  98.      */
  99.  
  100. STATIC STRPTR __regargs
  101. BuildString(STRPTR Source,STRPTR From,STRPTR To,BYTE Type,BOOLEAN ReceiveMode,STRPTR SingleFile,struct FileTransferInfo *Info,LONG *Error)
  102. {
  103.     struct List    *List;
  104.     STRPTR         Result = NULL;
  105.  
  106.     if(Info)
  107.     {
  108.         if(Info -> FileList . mlh_Head -> mln_Succ -> mln_Succ)
  109.             Info -> CurrentFile = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  110.         else
  111.             Info = NULL;
  112.     }
  113.  
  114.     *Error = 0;
  115.  
  116.     if(List = CreateList())
  117.     {
  118.         struct Node        *Node;
  119.         UBYTE             LocalBuffer[MAX_FILENAME_LENGTH],
  120.                      TempBuffer[MAX_FILENAME_LENGTH];
  121.         STRPTR             Index = Source,
  122.                      Dest = LocalBuffer;
  123.         struct FileRequester    *FileRequest;
  124.  
  125.         while(*Index && !(*Error))
  126.         {
  127.             if(*Index == '%')
  128.             {
  129.                 struct Node    *InsertHere = List -> lh_TailPred;
  130.                 BOOLEAN         InsertBefore = TRUE;
  131.  
  132.                 Index++;
  133.  
  134.                 if(!(*Index))
  135.                 {
  136.                     *Dest = 0;
  137.  
  138.                     if(LocalBuffer[0])
  139.                     {
  140.                         if(Node = CreateNode(LocalBuffer))
  141.                         {
  142.                             AddTail(List,Node);
  143.  
  144.                             LocalBuffer[0] = 0;
  145.                         }
  146.                         else
  147.                             *Error = ERR_NO_MEM;
  148.                     }
  149.  
  150.                     break;
  151.                 }
  152.  
  153.                 switch(*Index)
  154.                 {
  155.                     case 'f':
  156.  
  157.                         if(SingleFile)
  158.                         {
  159.                             if(Node = CreateArgName(SingleFile))
  160.                                 AddTail(List,Node);
  161.                             else
  162.                                 *Error = ERR_NO_MEM;
  163.  
  164.                             SingleFile = NULL;
  165.  
  166.                             break;
  167.                         }
  168.  
  169.                         if(Info)
  170.                         {
  171.                             if(Node = CreateArgName(Info -> CurrentFile -> Name))
  172.                                 AddTail(List,Node);
  173.                             else
  174.                                 *Error = ERR_NO_MEM;
  175.  
  176.                             if(Info -> CurrentFile -> Node . mln_Succ -> mln_Succ)
  177.                                 Info -> CurrentFile = (struct FileTransferNode *)Info -> CurrentFile -> Node . mln_Succ;
  178.                             else
  179.                                 Info = NULL;
  180.  
  181.                             break;
  182.                         }
  183.  
  184.                         LT_LockWindow(Window);
  185.  
  186.                         if(ReceiveMode)
  187.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  188.                         else
  189.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  190.  
  191.                         if(FileRequest)
  192.                         {
  193.                             if(Node = CreateArgName(TempBuffer))
  194.                                 AddTail(List,Node);
  195.                             else
  196.                                 *Error = ERR_NO_MEM;
  197.  
  198.                             FreeAslRequest(FileRequest);
  199.                         }
  200.                         else
  201.                             *Error = ERR_ABORTED;
  202.  
  203.                         LT_UnlockWindow(Window);
  204.  
  205.                         break;
  206.  
  207.                     case 'F':
  208.  
  209.                         if(SingleFile)
  210.                         {
  211.                             if(Node = CreateArgName(FilePart(SingleFile)))
  212.                                 AddTail(List,Node);
  213.                             else
  214.                                 *Error = ERR_NO_MEM;
  215.  
  216.                             SingleFile = NULL;
  217.  
  218.                             break;
  219.                         }
  220.  
  221.                         if(Info)
  222.                         {
  223.                             if(Node = CreateArgName(FilePart(Info -> CurrentFile -> Name)))
  224.                                 AddTail(List,Node);
  225.                             else
  226.                                 *Error = ERR_NO_MEM;
  227.  
  228.                             if(Info -> CurrentFile -> Node . mln_Succ -> mln_Succ)
  229.                                 Info -> CurrentFile = (struct FileTransferNode *)Info -> CurrentFile -> Node . mln_Succ;
  230.                             else
  231.                                 Info = NULL;
  232.  
  233.                             break;
  234.                         }
  235.  
  236.                         LT_LockWindow(Window);
  237.  
  238.                         if(ReceiveMode)
  239.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  240.                         else
  241.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  242.  
  243.                         if(FileRequest)
  244.                         {
  245.                             if(Node = CreateArgName(FilePart(TempBuffer)))
  246.                                 AddTail(List,Node);
  247.                             else
  248.                                 *Error = ERR_NO_MEM;
  249.  
  250.                             FreeAslRequest(FileRequest);
  251.                         }
  252.                         else
  253.                             *Error = ERR_ABORTED;
  254.  
  255.                         LT_UnlockWindow(Window);
  256.  
  257.                         break;
  258.  
  259.                     case 'm':
  260.  
  261.                         if(SingleFile)
  262.                         {
  263.                             if(Node = CreateArgName(SingleFile))
  264.                                 AddTail(List,Node);
  265.                             else
  266.                                 *Error = ERR_NO_MEM;
  267.  
  268.                             SingleFile = NULL;
  269.  
  270.                             break;
  271.                         }
  272.  
  273.                         if(Info)
  274.                         {
  275.                             struct FileTransferNode *SomeNode = Info -> CurrentFile;
  276.  
  277.                             while(SomeNode -> Node . mln_Succ && !(*Error))
  278.                             {
  279.                                 if(Node = CreateArgName(SomeNode -> Name))
  280.                                     AddTail(List,Node);
  281.                                 else
  282.                                     *Error = ERR_NO_MEM;
  283.  
  284.                                 SomeNode = (struct FileTransferNode *)SomeNode -> Node . mln_Succ;
  285.                             }
  286.  
  287.                             Info = NULL;
  288.  
  289.                             break;
  290.                         }
  291.  
  292.                         LT_LockWindow(Window);
  293.  
  294.                         TempBuffer[0] = 0;
  295.  
  296.                         if(ReceiveMode)
  297.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  298.                         else
  299.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  300.  
  301.                         LT_UnlockWindow(Window);
  302.  
  303.                         if(FileRequest)
  304.                         {
  305.                             LONG i;
  306.  
  307.                             if(TempBuffer[0] && FileRequest -> fr_NumArgs == 1)
  308.                             {
  309.                                 if(Node = CreateArgName(TempBuffer))
  310.                                 {
  311.                                     AddTail(List,Node);
  312.  
  313.                                     break;
  314.                                 }
  315.                                 else
  316.                                     *Error = ERR_NO_MEM;
  317.                             }
  318.  
  319.                             for(i = 0 ; i < FileRequest -> fr_NumArgs && !(*Error) ; i++)
  320.                             {
  321.                                 if(FileRequest -> fr_ArgList[i] . wa_Lock)
  322.                                 {
  323.                                     if(NameFromLock(FileRequest -> fr_ArgList[i] . wa_Lock,TempBuffer,MAX_FILENAME_LENGTH))
  324.                                     {
  325.                                         if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  326.                                         {
  327.                                             if(Node = CreateArgName(TempBuffer))
  328.                                                 AddTail(List,Node);
  329.                                             else
  330.                                                 *Error = ERR_NO_MEM;
  331.                                         }
  332.                                         else
  333.                                             *Error = IoErr();
  334.                                     }
  335.                                     else
  336.                                         *Error = IoErr();
  337.                                 }
  338.                                 else
  339.                                 {
  340.                                     strcpy(TempBuffer,FileRequest -> fr_Drawer);
  341.  
  342.                                     if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  343.                                     {
  344.                                         if(Node = CreateArgName(TempBuffer))
  345.                                             AddTail(List,Node);
  346.                                         else
  347.                                             *Error = ERR_NO_MEM;
  348.                                     }
  349.                                     else
  350.                                         *Error = IoErr();
  351.                                 }
  352.                             }
  353.  
  354.                             FreeAslRequest(FileRequest);
  355.                         }
  356.                         else
  357.                             *Error = ERR_ABORTED;
  358.  
  359.                         break;
  360.  
  361.                     case 'M':
  362.  
  363.                         if(SingleFile)
  364.                         {
  365.                             if(Node = CreateArgName(FilePart(SingleFile)))
  366.                                 AddTail(List,Node);
  367.                             else
  368.                                 *Error = ERR_NO_MEM;
  369.  
  370.                             SingleFile = NULL;
  371.  
  372.                             break;
  373.                         }
  374.  
  375.                         if(Info)
  376.                         {
  377.                             struct FileTransferNode *SomeNode = Info -> CurrentFile;
  378.  
  379.                             while(SomeNode -> Node . mln_Succ && !(*Error))
  380.                             {
  381.                                 if(Node = CreateArgName(FilePart(SomeNode -> Name)))
  382.                                     AddTail(List,Node);
  383.                                 else
  384.                                     *Error = ERR_NO_MEM;
  385.  
  386.                                 SomeNode = (struct FileTransferNode *)SomeNode -> Node . mln_Succ;
  387.                             }
  388.  
  389.                             Info = NULL;
  390.  
  391.                             break;
  392.                         }
  393.  
  394.                         LT_LockWindow(Window);
  395.  
  396.                         TempBuffer[0] = 0;
  397.  
  398.                         if(ReceiveMode)
  399.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  400.                         else
  401.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  402.  
  403.                         LT_UnlockWindow(Window);
  404.  
  405.                         if(FileRequest)
  406.                         {
  407.                             LONG i;
  408.  
  409.                             if(TempBuffer[0] && FileRequest -> fr_NumArgs == 1)
  410.                             {
  411.                                 if(Node = CreateArgName(FilePart(TempBuffer)))
  412.                                 {
  413.                                     AddTail(List,Node);
  414.  
  415.                                     break;
  416.                                 }
  417.                                 else
  418.                                     *Error = ERR_NO_MEM;
  419.                             }
  420.  
  421.                             for(i = 0 ; i < FileRequest -> fr_NumArgs && !(*Error) ; i++)
  422.                             {
  423.                                 if(FileRequest -> fr_ArgList[i] . wa_Lock)
  424.                                 {
  425.                                     if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  426.                                     {
  427.                                         if(Node = CreateArgName(TempBuffer))
  428.                                             AddTail(List,Node);
  429.                                         else
  430.                                             *Error = ERR_NO_MEM;
  431.                                     }
  432.                                     else
  433.                                         *Error = IoErr();
  434.                                 }
  435.                                 else
  436.                                 {
  437.                                     if(Node = CreateArgName(FileRequest -> fr_ArgList[i] . wa_Name))
  438.                                         AddTail(List,Node);
  439.                                     else
  440.                                         *Error = ERR_NO_MEM;
  441.                                 }
  442.                             }
  443.  
  444.                             FreeAslRequest(FileRequest);
  445.                         }
  446.                         else
  447.                             *Error = ERR_ABORTED;
  448.  
  449.                         break;
  450.  
  451.                     case 'b':
  452.                     case 'B':
  453.  
  454.                         SPrintf(SharedBuffer,"%ld",Config -> SerialConfig -> BaudRate);
  455.  
  456.                         if(Node = CreateNode(SharedBuffer))
  457.                             AddTail(List,Node);
  458.                         else
  459.                             *Error = ERR_NO_MEM;
  460.  
  461.                         break;
  462.  
  463.                     case 'c':
  464.                     case 'C':
  465.  
  466.                         SPrintf(SharedBuffer,"%ld",DTERate ? DTERate : Config -> SerialConfig -> BaudRate);
  467.  
  468.                         if(Node = CreateNode(SharedBuffer))
  469.                             AddTail(List,Node);
  470.                         else
  471.                             *Error = ERR_NO_MEM;
  472.  
  473.                         break;
  474.  
  475.                     case 'p':
  476.                     case 'P':
  477.  
  478.                         if(Node = CreateArgName(RexxPortName))
  479.                             AddTail(List,Node);
  480.                         else
  481.                             *Error = ERR_NO_MEM;
  482.  
  483.                         break;
  484.  
  485.                     case 'd':
  486.                     case 'D':
  487.  
  488.                         if(Node = CreateArgName(Config -> SerialConfig -> SerialDevice))
  489.                             AddTail(List,Node);
  490.                         else
  491.                             *Error = ERR_NO_MEM;
  492.  
  493.                         break;
  494.  
  495.                     case 'u':
  496.                     case 'U':
  497.  
  498.                         SPrintf(SharedBuffer,"%ld",Config -> SerialConfig -> UnitNumber);
  499.  
  500.                         if(Node = CreateNode(SharedBuffer))
  501.                             AddTail(List,Node);
  502.                         else
  503.                             *Error = ERR_NO_MEM;
  504.  
  505.                         break;
  506.  
  507.                     case '<':
  508.  
  509.                         if(Node = CreateArgName(From))
  510.                             AddTail(List,Node);
  511.                         else
  512.                             *Error = ERR_NO_MEM;
  513.  
  514.                         break;
  515.  
  516.                     case '>':
  517.  
  518.                         if(Node = CreateArgName(To))
  519.                             AddTail(List,Node);
  520.                         else
  521.                             *Error = ERR_NO_MEM;
  522.  
  523.                         break;
  524.  
  525.                     case 's':
  526.                     case 'S':
  527.  
  528.                         if(!GetPubScreenName(Window -> WScreen,SharedBuffer))
  529.                             SharedBuffer[0] = 0;
  530.  
  531.                         if(Node = CreateArgName(SharedBuffer))
  532.                             AddTail(List,Node);
  533.                         else
  534.                             *Error = ERR_NO_MEM;
  535.  
  536.                         break;
  537.  
  538.                     default:
  539.  
  540.                         *Dest = *Index;
  541.  
  542.                         InsertBefore = FALSE;
  543.  
  544.                         break;
  545.                 }
  546.  
  547.                 if(InsertBefore && Node)
  548.                 {
  549.                     struct Node *OtherNode;
  550.  
  551.                     *Dest = 0;
  552.  
  553.                     if(LocalBuffer[0])
  554.                     {
  555.                         if(OtherNode = CreateNode(LocalBuffer))
  556.                         {
  557.                             Insert(List,OtherNode,InsertHere);
  558.  
  559.                             LocalBuffer[0] = 0;
  560.                         }
  561.                         else
  562.                             *Error = ERR_NO_MEM;
  563.                     }
  564.  
  565.                     Dest = LocalBuffer;
  566.                 }
  567.             }
  568.             else
  569.                 *Dest++ = *Index;
  570.  
  571.             Index++;
  572.         }
  573.  
  574.         *Dest = 0;
  575.  
  576.         if(LocalBuffer[0] && !(*Error))
  577.         {
  578.             if(Node = CreateNode(LocalBuffer))
  579.                 AddTail(List,Node);
  580.             else
  581.                 *Error = ERR_NO_MEM;
  582.         }
  583.  
  584.         if(!(*Error))
  585.         {
  586.             if(List -> lh_Head -> ln_Succ)
  587.             {
  588.                 LONG Total = 0,Len;
  589.  
  590.                 for(Node = List -> lh_Head ; Node -> ln_Succ ; Node = Node -> ln_Succ)
  591.                     Total += strlen(Node -> ln_Name) + 1;
  592.  
  593.                 if(Result = (STRPTR)AllocVecPooled(Total,MEMF_ANY))
  594.                 {
  595.                     STRPTR Buffer = Result;
  596.  
  597.                     for(Node = List -> lh_Head ; Node -> ln_Succ ; Node = Node -> ln_Succ)
  598.                     {
  599.                         Len = strlen(Node -> ln_Name);
  600.  
  601.                         memcpy(Buffer,Node -> ln_Name,Len);
  602.  
  603.                         Buffer += Len;
  604.  
  605.                         *Buffer++ = ' ';
  606.                     }
  607.  
  608.                     Buffer[-1] = 0;
  609.                 }
  610.             }
  611.             else
  612.                 Result = "";
  613.         }
  614.  
  615.         DeleteList(List);
  616.     }
  617.     else
  618.         *Error = ERR_NO_MEM;
  619.  
  620.     return(Result);
  621. }
  622.  
  623.     /* ReplaceName(STRPTR Original):
  624.      *
  625.      *    Replace a filename with a mangled version for
  626.      *    file uploads.
  627.      */
  628.  
  629. STATIC STRPTR __regargs
  630. ReplaceName(STRPTR Source)
  631. {
  632.     if(Config -> TransferConfig -> MangleFileNames)
  633.     {
  634.         UBYTE LocalName[MAX_FILENAME_LENGTH],*Char;
  635.  
  636.         strcpy(OriginalName,Source);
  637.  
  638.         ShrinkName(FilePart(Source),LocalName,12,TRUE);
  639.  
  640.         strcpy(ShrunkenName,Source);
  641.  
  642.         Char = PathPart(ShrunkenName);
  643.  
  644.         *Char = 0;
  645.  
  646.         AddPart(ShrunkenName,LocalName,MAX_FILENAME_LENGTH);
  647.  
  648.         return(ShrunkenName);
  649.     }
  650.     else
  651.     {
  652.         OriginalName[0] = 0;
  653.  
  654.         return(Source);
  655.     }
  656. }
  657.  
  658.     /* FreeFileTransferInfo(struct FileTransferInfo *Info):
  659.      *
  660.      *    Free a file transfer info list as allocated
  661.      *    by AllocFileTransferInfo() and AddFileTransferNode().
  662.      */
  663.  
  664. VOID __regargs
  665. FreeFileTransferInfo(struct FileTransferInfo *Info)
  666. {
  667.     if(Info)
  668.     {
  669.         struct FileTransferNode    *Node,
  670.                     *Next;
  671.  
  672.         Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  673.  
  674.         while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
  675.         {
  676.             FreeVecPooled(Node);
  677.  
  678.             Node = Next;
  679.         }
  680.  
  681.         FreeVecPooled(Info);
  682.     }
  683. }
  684.  
  685.     /* AllocFileTransferInfo():
  686.      *
  687.      *    Allocate a FileTransferInfo structure for use with
  688.      *    AddFileTransferNode().
  689.      */
  690.  
  691. struct FileTransferInfo *
  692. AllocFileTransferInfo()
  693. {
  694.     struct FileTransferInfo *Info;
  695.  
  696.     if(Info = (struct FileTransferInfo *)AllocVecPooled(sizeof(struct FileTransferInfo),MEMF_ANY | MEMF_CLEAR))
  697.     {
  698.         NewList((struct List *)&Info -> FileList);
  699.  
  700.         return(Info);
  701.     }
  702.  
  703.     return(NULL);
  704. }
  705.  
  706.     /* AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size):
  707.      *
  708.      *    Allocate a file transfer information node.
  709.      */
  710.  
  711. BYTE __regargs
  712. AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size)
  713. {
  714.     struct FileTransferNode    *Node;
  715.     WORD             Len = strlen(Name) + 1;
  716.  
  717.     if(Node = (struct FileTransferNode *)AllocVecPooled(sizeof(struct FileTransferNode) + Len,MEMF_ANY))
  718.     {
  719.         Node -> Size    = Size;
  720.         Node -> Name    = (STRPTR)(Node + 1);
  721.  
  722.         strcpy(Node -> Name,Name);
  723.  
  724.         AddTail((struct List *)&Info -> FileList,(struct Node *)Node);
  725.  
  726.         Info -> TotalSize += Size;
  727.  
  728.         Info -> TotalFiles++;
  729.  
  730.         return(TRUE);
  731.     }
  732.     else
  733.         return(FALSE);
  734. }
  735.  
  736.     /* Compare(struct FileTransferNode **A,struct FileTransferNode **B):
  737.      *
  738.      *    Local subroutine required by qsort().
  739.      */
  740.  
  741. STATIC int __stdargs
  742. Compare(struct FileTransferNode **A,struct FileTransferNode **B)
  743. {
  744.     return(Stricmp(FilePart((*A) -> Name),FilePart((*B) -> Name)));
  745. }
  746.  
  747.     /* SortFileTransferInfo(struct FileTransferInfo *Info):
  748.      *
  749.      *    Sorts the file transfer information list in ascending
  750.      *    order, but makes sure that the files are sorted
  751.      *    in descending order (i.e. the larger files come
  752.      *    first and files of equal size are sorted
  753.      *    lexically).
  754.      */
  755.  
  756. VOID __regargs
  757. SortFileTransferInfo(struct FileTransferInfo *Info)
  758. {
  759.     if(Info -> TotalFiles > 1)
  760.     {
  761.         struct FileTransferNode **NodeList;
  762.  
  763.         if(NodeList = (struct FileTransferNode **)AllocVecPooled(sizeof(struct FileTransferNode *) * Info -> TotalFiles,MEMF_ANY))
  764.         {
  765.             struct FileTransferNode    *Node,
  766.                         *Next;
  767.             LONG             i = 0;
  768.  
  769.             Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  770.  
  771.             while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
  772.             {
  773.                 NodeList[i++] = Node;
  774.  
  775.                 Node = Next;
  776.             }
  777.  
  778.             qsort((APTR)NodeList,Info -> TotalFiles,sizeof(struct FileTransferNode *),Compare);
  779.  
  780.             NewList((struct List *)&Info -> FileList);
  781.  
  782.             for(i = 0 ; i < Info -> TotalFiles ; i++)
  783.                 AddTail((struct List *)&Info -> FileList,(struct Node *)&NodeList[i] -> Node);
  784.  
  785.             FreeVecPooled(NodeList);
  786.         }
  787.     }
  788.  
  789.     Info -> DoneSize    = 0;
  790.     Info -> DoneFiles    = 0;
  791.  
  792.     Info -> CurrentFile    = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  793.     Info -> CurrentSize    = Info -> CurrentFile -> Size;
  794. }
  795.  
  796.     /* BuildFileTransferInfo(struct FileRequester *FileRequester):
  797.      *
  798.      *    Build a file transfer information list from
  799.      *    information provided by a FileRequester structure.
  800.      */
  801.  
  802. struct FileTransferInfo * __regargs
  803. BuildFileTransferInfo(struct FileRequester *FileRequester)
  804. {
  805.     struct FileTransferInfo    *Info;
  806.     LONG             FilesFound = 0;
  807.  
  808.     if(Info = AllocFileTransferInfo())
  809.     {
  810.         BYTE    Success = FALSE;
  811.         BPTR    NewLock,
  812.             OldLock;
  813.  
  814.         if(NewLock = Lock(FileRequester -> rf_Dir,ACCESS_READ))
  815.         {
  816.             OldLock = CurrentDir(NewLock);
  817.  
  818.             if(FileRequester -> rf_NumArgs)
  819.             {
  820.                 struct FileInfoBlock *FileInfo;
  821.  
  822.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  823.                 {
  824.                     BPTR         FileLock;
  825.                     struct WBArg    *ArgList = FileRequester -> rf_ArgList;
  826.                     LONG         i;
  827.  
  828.                     Success = TRUE;
  829.  
  830.                     for(i = 0 ; Success && i < FileRequester -> rf_NumArgs ; i++)
  831.                     {
  832.                         if(ArgList[i] . wa_Name)
  833.                         {
  834.                             if(ArgList[i] . wa_Lock)
  835.                             {
  836.                                 CurrentDir(ArgList[i] . wa_Lock);
  837.  
  838.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  839.                                 {
  840.                                     if(Examine(FileLock,FileInfo))
  841.                                     {
  842.                                         if(FileInfo -> fib_DirEntryType < 0)
  843.                                         {
  844.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  845.                                             {
  846.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  847.                                                     Success = FALSE;
  848.                                                 else
  849.                                                     FilesFound++;
  850.                                             }
  851.                                         }
  852.                                     }
  853.  
  854.                                     UnLock(FileLock);
  855.                                 }
  856.  
  857.                                 CurrentDir(NewLock);
  858.                             }
  859.                             else
  860.                             {
  861.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  862.                                 {
  863.                                     if(Examine(FileLock,FileInfo))
  864.                                     {
  865.                                         if(FileInfo -> fib_DirEntryType < 0)
  866.                                         {
  867.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  868.                                             {
  869.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  870.                                                     Success = FALSE;
  871.                                                 else
  872.                                                     FilesFound++;
  873.                                             }
  874.                                         }
  875.                                     }
  876.  
  877.                                     UnLock(FileLock);
  878.                                 }
  879.                             }
  880.                         }
  881.                     }
  882.                 }
  883.  
  884.                 FreeDosObject(DOS_FIB,FileInfo);
  885.             }
  886.             else
  887.             {
  888.                 struct AnchorPath *Anchor;
  889.  
  890.                 STRPTR FileName;
  891.  
  892.                 if(FileRequester -> rf_NumArgs > 1 && FileRequester -> rf_ArgList)
  893.                     FileName = FileRequester -> rf_ArgList -> wa_Name;
  894.                 else
  895.                     FileName = FileRequester -> rf_File;
  896.  
  897.                 if(Anchor = (struct AnchorPath *)AllocVecPooled(sizeof(struct AnchorPath),MEMF_ANY | MEMF_CLEAR))
  898.                 {
  899.                     if(!MatchFirst(FileName,Anchor))
  900.                     {
  901.                         Success = TRUE;
  902.  
  903.                         if(Anchor -> ap_Info . fib_DirEntryType < 0)
  904.                         {
  905.                             if(NameFromLock(NewLock,SharedBuffer,512))
  906.                             {
  907.                                 if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  908.                                 {
  909.                                     if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  910.                                         Success = FALSE;
  911.                                     else
  912.                                         FilesFound++;
  913.                                 }
  914.                             }
  915.                         }
  916.  
  917.                         if(Success)
  918.                         {
  919.                             while(!MatchNext(Anchor))
  920.                             {
  921.                                 if(NameFromLock(NewLock,SharedBuffer,512))
  922.                                 {
  923.                                     if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  924.                                     {
  925.                                         if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  926.                                         {
  927.                                             Success = FALSE;
  928.  
  929.                                             break;
  930.                                         }
  931.                                         else
  932.                                             FilesFound++;
  933.                                     }
  934.                                 }
  935.                             }
  936.                         }
  937.  
  938.                         if(IoErr() != ERROR_NO_MORE_ENTRIES)
  939.                             Success = FALSE;
  940.                     }
  941.  
  942.                     MatchEnd(Anchor);
  943.  
  944.                     FreeVecPooled(Anchor);
  945.                 }
  946.             }
  947.  
  948.             CurrentDir(OldLock);
  949.  
  950.             UnLock(NewLock);
  951.         }
  952.  
  953.         if(Success && FilesFound)
  954.         {
  955.             SortFileTransferInfo(Info);
  956.  
  957.             return(Info);
  958.         }
  959.         else
  960.             FreeFileTransferInfo(Info);
  961.     }
  962.  
  963.     return(NULL);
  964. }
  965.  
  966.     /* SendTextFile(STRPTR TheFile):
  967.      *
  968.      *    Send a single text file via xpr.
  969.      */
  970.  
  971. VOID __regargs
  972. SendTextFile(BYTE Type,STRPTR TheFile)
  973. {
  974.     STRPTR    From,To,Name;
  975.     BYTE    Mode;
  976.  
  977.     TheFile = ReplaceName(TheFile);
  978.  
  979.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIUploadType == XFER_INTERNAL)
  980.     {
  981.         InternalASCIIUpload(TheFile,TRUE);
  982.  
  983.         return;
  984.     }
  985.  
  986.     switch(Type)
  987.     {
  988.         case TRANSFER_BINARY:
  989.  
  990.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  991.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  992.             From    = Config -> PathConfig -> BinaryUploadPath;
  993.             To    = Config -> PathConfig -> BinaryDownloadPath;
  994.             break;
  995.  
  996.         case TRANSFER_TEXT:
  997.  
  998.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  999.             Mode    = Config -> TransferConfig -> TextUploadType;
  1000.             From    = Config -> PathConfig -> TextUploadPath;
  1001.             To    = Config -> PathConfig -> TextDownloadPath;
  1002.             break;
  1003.  
  1004.         case TRANSFER_ASCII:
  1005.  
  1006.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1007.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1008.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1009.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1010.             break;
  1011.     }
  1012.  
  1013.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1014.     {
  1015.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1016.         Mode    = XFER_EXTERNALPROGRAM;
  1017.     }
  1018.  
  1019.     if(Mode == XFER_EXTERNALPROGRAM)
  1020.     {
  1021.         STRPTR    String;
  1022.         LONG    Error;
  1023.  
  1024.         BlockWindows();
  1025.  
  1026.         if(String = BuildString(Name,From,To,Type,FALSE,TheFile,NULL,&Error))
  1027.         {
  1028.             ClearSerial();
  1029.  
  1030.             LaunchCommand(String);
  1031.  
  1032.             RestartSerial(FALSE);
  1033.  
  1034.             FreeVecPooled(String);
  1035.         }
  1036.  
  1037.         ReleaseWindows();
  1038.     }
  1039.     else
  1040.     {
  1041.         BYTE OldStatus = Status;
  1042.         BPTR NewDir,OldDir;
  1043.  
  1044.         if(Type == TRANSFER_ASCII)
  1045.             NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ);
  1046.         else
  1047.             NewDir = Lock(Config -> PathConfig -> TextUploadPath,ACCESS_READ);
  1048.  
  1049.         if(NewDir)
  1050.             OldDir = CurrentDir(NewDir);
  1051.         else
  1052.             OldDir = NULL;
  1053.  
  1054.         Uploading = TRUE;
  1055.  
  1056.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1057.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1058.  
  1059.             /* If not initialized, try to set up a new
  1060.              * external transfer protocol.
  1061.              */
  1062.  
  1063.         if(!XProtocolBase)
  1064.         {
  1065.             if(SelectProtocol(LastXprLibrary,Window))
  1066.             {
  1067.                 if(ProtocolSetup(FALSE))
  1068.                 {
  1069.                     SaveProtocolOpts();
  1070.  
  1071.                     strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  1072.                 }
  1073.             }
  1074.         }
  1075.  
  1076.         if(XProtocolBase)
  1077.         {
  1078.             SetTransferMenu(TRUE);
  1079.  
  1080.             XprIO -> xpr_filename = TheFile;
  1081.  
  1082.             if(TransferPanel(SendQuery[TRANSFER_TEXT]))
  1083.             {
  1084.                 Status = STATUS_UPLOAD;
  1085.  
  1086.                 ClearSerial();
  1087.  
  1088.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[TRANSFER_TEXT]);
  1089.  
  1090.                 if(ReadRequest && WriteRequest)
  1091.                 {
  1092.                     if(XProtocolSend(XprIO))
  1093.                         TransferFailed = FALSE;
  1094.                     else
  1095.                         TransferFailed = TRUE;
  1096.                 }
  1097.                 else
  1098.                     TransferFailed = TRUE;
  1099.  
  1100.                 if(TransferFailed || TransferAborted)
  1101.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1102.                 else
  1103.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1104.  
  1105.                 if(TransferFailed || TransferError)
  1106.                 {
  1107.                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1108.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1109.  
  1110.                     DeleteTransferPanel(TRUE);
  1111.                 }
  1112.                 else
  1113.                 {
  1114.                     if(TransferWindow)
  1115.                     {
  1116.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1117.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1118.  
  1119.                         WaitTime(2,0);
  1120.                     }
  1121.  
  1122.                     DeleteTransferPanel(FALSE);
  1123.                 }
  1124.  
  1125.                 Status = OldStatus;
  1126.  
  1127.                 RestartSerial(FALSE);
  1128.             }
  1129.         }
  1130.         else
  1131.             SetTransferMenu(FALSE);
  1132.  
  1133.         if(OldDir)
  1134.             CurrentDir(OldDir);
  1135.  
  1136.         if(NewDir)
  1137.             UnLock(NewDir);
  1138.  
  1139.         if(SendAbort && UsesZModem)
  1140.             SerWrite(ZModemCancel,20);
  1141.  
  1142.         SendAbort = FALSE;
  1143.  
  1144.         Uploading = FALSE;
  1145.  
  1146.         if(Config -> CommandConfig -> UploadMacro[0])
  1147.             SerialCommand(Config -> CommandConfig -> UploadMacro);
  1148.  
  1149.         DidTransfer = FALSE;
  1150.     }
  1151. }
  1152.  
  1153.     /* StartXprReceive():
  1154.      *
  1155.      *    Receive files via xpr.
  1156.      */
  1157.  
  1158. VOID __regargs
  1159. StartXprReceive(BYTE Type,STRPTR Name,BYTE WaitForIt)
  1160. {
  1161.     STRPTR    From,To,Cmd;
  1162.     BYTE    Mode;
  1163.  
  1164.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1165.     {
  1166.         InternalASCIIDownload(Name,WaitForIt);
  1167.  
  1168.         return;
  1169.     }
  1170.  
  1171.     switch(Type)
  1172.     {
  1173.         case TRANSFER_BINARY:
  1174.  
  1175.             Cmd    = Config -> TransferConfig -> BinaryDownloadLibrary;
  1176.             Mode    = Config -> TransferConfig -> BinaryDownloadType;
  1177.             From    = Config -> PathConfig -> BinaryUploadPath;
  1178.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1179.             break;
  1180.  
  1181.         case TRANSFER_TEXT:
  1182.  
  1183.             Cmd    = Config -> TransferConfig -> TextDownloadLibrary;
  1184.             Mode    = Config -> TransferConfig -> TextDownloadType;
  1185.             From    = Config -> PathConfig -> TextUploadPath;
  1186.             To    = Config -> PathConfig -> TextDownloadPath;
  1187.             break;
  1188.  
  1189.         case TRANSFER_ASCII:
  1190.  
  1191.             Cmd    = Config -> TransferConfig -> ASCIIDownloadLibrary;
  1192.             Mode    = Config -> TransferConfig -> ASCIIDownloadType;
  1193.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1194.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1195.             break;
  1196.     }
  1197.  
  1198.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1199.     {
  1200.         Cmd    = Config -> TransferConfig -> DefaultLibrary;
  1201.         Mode    = XFER_EXTERNALPROGRAM;
  1202.     }
  1203.  
  1204.     if(Mode == XFER_EXTERNALPROGRAM)
  1205.     {
  1206.         STRPTR    String;
  1207.         LONG    Error;
  1208.  
  1209.         BlockWindows();
  1210.  
  1211.         if(String = BuildString(Cmd,From,To,Type,TRUE,Name,NULL,&Error))
  1212.         {
  1213.             ClearSerial();
  1214.  
  1215.             LaunchCommand(String);
  1216.  
  1217.             RestartSerial(TRUE);
  1218.  
  1219.             FreeVecPooled(String);
  1220.         }
  1221.  
  1222.         ReleaseWindows();
  1223.     }
  1224.     else
  1225.     {
  1226.         struct FileRequester    *FileRequest;
  1227.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  1228.         BYTE             OldStatus = Status;
  1229.         BPTR             NewDir,OldDir;
  1230.  
  1231.         ClearGenericList(GenericListTable[GLIST_DOWNLOAD]);
  1232.  
  1233.         LocalizeString(ReceiveQuery,MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT,MSG_TERMTRANSFER_DOWNLOAD_ASCII_TXT);
  1234.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1235.  
  1236.             /* Select the download path. */
  1237.  
  1238.         switch(Type)
  1239.         {
  1240.             case TRANSFER_BINARY:
  1241.  
  1242.                 DownloadPath = Config -> PathConfig -> BinaryDownloadPath;
  1243.                 break;
  1244.  
  1245.             case TRANSFER_TEXT:
  1246.  
  1247.                 DownloadPath = Config -> PathConfig -> TextDownloadPath;
  1248.                 break;
  1249.  
  1250.             case TRANSFER_ASCII:
  1251.  
  1252.                 DownloadPath = Config -> PathConfig -> ASCIIDownloadPath;
  1253.                 break;
  1254.         }
  1255.  
  1256.         if(DownloadPath[0])
  1257.         {
  1258.             if(NewDir = Lock(DownloadPath,ACCESS_READ))
  1259.                 OldDir = CurrentDir(NewDir);
  1260.             else
  1261.                 OldDir = NULL;
  1262.         }
  1263.         else
  1264.             NewDir = OldDir = NULL;
  1265.  
  1266.         BlockWindows();
  1267.  
  1268.             /* Set up the library if necessary. */
  1269.  
  1270.         if(!XProtocolBase)
  1271.         {
  1272.             if(SelectProtocol(LastXprLibrary,Window))
  1273.             {
  1274.                 if(ProtocolSetup(FALSE))
  1275.                 {
  1276.                     SaveProtocolOpts();
  1277.  
  1278.                     strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  1279.                 }
  1280.             }
  1281.         }
  1282.  
  1283.         if(XProtocolBase)
  1284.         {
  1285.             SetTransferMenu(TRUE);
  1286.  
  1287.                 /* Do we need to ask the user for
  1288.                  * the destination file name?
  1289.                  */
  1290.  
  1291.             if(TransferBits & XPRS_NORECREQ)
  1292.             {
  1293.                     /* Obviously not, let's open
  1294.                      * the transfer info window as
  1295.                      * usual and download the file(s).
  1296.                      */
  1297.  
  1298.                 if(TransferPanel(ReceiveQuery[Type]))
  1299.                 {
  1300.                     Status = STATUS_DOWNLOAD;
  1301.  
  1302.                     ClearSerial();
  1303.  
  1304.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  1305.  
  1306.                         /* Receive the data. */
  1307.  
  1308.                     if(ReadRequest && WriteRequest)
  1309.                     {
  1310.                         if(XProtocolReceive(XprIO))
  1311.                             TransferFailed = FALSE;
  1312.                         else
  1313.                             TransferFailed = TRUE;
  1314.                     }
  1315.                     else
  1316.                         TransferFailed = TRUE;
  1317.  
  1318.                         /* In case the transfer has been aborted,
  1319.                          * flush the input buffer of dirty data.
  1320.                          */
  1321.  
  1322.                     if(TransferAborted)
  1323.                         xpr_sflush();
  1324.  
  1325.                     if(TransferAborted || TransferFailed)
  1326.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1327.                     else
  1328.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1329.  
  1330.                     if(TransferFailed || TransferError)
  1331.                     {
  1332.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1333.                             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1334.  
  1335.                         DeleteTransferPanel(WaitForIt);
  1336.                     }
  1337.                     else
  1338.                     {
  1339.                         if(TransferWindow)
  1340.                         {
  1341.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1342.                                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1343.  
  1344.                             WaitTime(2,0);
  1345.                         }
  1346.  
  1347.                         DeleteTransferPanel(FALSE);
  1348.                     }
  1349.  
  1350.                     Status = OldStatus;
  1351.  
  1352.                         /* Queue another read request. */
  1353.  
  1354.                     RestartSerial(FALSE);
  1355.                 }
  1356.             }
  1357.             else
  1358.             {
  1359.                 if(!Name)
  1360.                 {
  1361.                     if(FileRequest = GetFile(Window,ReceiveQuery[Type],DownloadPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE))
  1362.                     {
  1363.                             /* Save the download path. */
  1364.  
  1365.                         strcpy(DownloadPath,FileRequest -> rf_Dir);
  1366.  
  1367.                         ConfigChanged = TRUE;
  1368.  
  1369.                             /* Install the name of the file to receive. */
  1370.  
  1371.                         XprIO -> xpr_filename = DummyBuffer;
  1372.  
  1373.                         FreeAslRequest(FileRequest);
  1374.  
  1375.                         Name = DummyBuffer;
  1376.                     }
  1377.                 }
  1378.                 else
  1379.                 {
  1380.                     STRPTR Index;
  1381.  
  1382.                     strcpy(DownloadPath,Name);
  1383.  
  1384.                     ConfigChanged = TRUE;
  1385.  
  1386.                     Index = PathPart(DownloadPath);
  1387.  
  1388.                     *Index = 0;
  1389.  
  1390.                     XprIO -> xpr_filename = Name;
  1391.                 }
  1392.  
  1393.                     /* Download the file(s). */
  1394.  
  1395.                 if(Name)
  1396.                 {
  1397.                         /* Open the transfer panel. */
  1398.  
  1399.                     if(TransferPanel(ReceiveQuery[Type]))
  1400.                     {
  1401.                         Status = STATUS_DOWNLOAD;
  1402.  
  1403.                         ClearSerial();
  1404.  
  1405.                         LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  1406.  
  1407.                             /* Receive the file. */
  1408.  
  1409.                         if(ReadRequest && WriteRequest)
  1410.                         {
  1411.                             if(XProtocolReceive(XprIO))
  1412.                                 TransferFailed = FALSE;
  1413.                             else
  1414.                                 TransferFailed = TRUE;
  1415.                         }
  1416.                         else
  1417.                             TransferFailed = TRUE;
  1418.  
  1419.                             /* In case the transfer has been aborted,
  1420.                              * flush the input buffer of dirty data.
  1421.                              */
  1422.  
  1423.                         if(TransferAborted)
  1424.                             xpr_sflush();
  1425.  
  1426.                         if(TransferAborted || TransferFailed)
  1427.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1428.                         else
  1429.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1430.  
  1431.                         if(TransferFailed || TransferError)
  1432.                         {
  1433.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1434.                                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1435.  
  1436.                             DeleteTransferPanel(WaitForIt);
  1437.                         }
  1438.                         else
  1439.                         {
  1440.                             if(TransferWindow)
  1441.                             {
  1442.                                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1443.                                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1444.  
  1445.                                 WaitTime(2,0);
  1446.                             }
  1447.  
  1448.                             DeleteTransferPanel(FALSE);
  1449.                         }
  1450.  
  1451.                         Status = OldStatus;
  1452.  
  1453.                             /* Queue another read
  1454.                              * request.
  1455.                              */
  1456.  
  1457.                         RestartSerial(FALSE);
  1458.                     }
  1459.                 }
  1460.             }
  1461.         }
  1462.         else
  1463.             SetTransferMenu(FALSE);
  1464.  
  1465.         if(OldDir)
  1466.             CurrentDir(OldDir);
  1467.  
  1468.         if(NewDir)
  1469.             UnLock(NewDir);
  1470.  
  1471.         if(SendAbort && UsesZModem)
  1472.             SerWrite(ZModemCancel,20);
  1473.  
  1474.         SendAbort = FALSE;
  1475.  
  1476.         ReleaseWindows();
  1477.  
  1478.         DownloadPath = NULL;
  1479.  
  1480.         DidTransfer = FALSE;
  1481.  
  1482.         if(WaitForIt)
  1483.         {
  1484.             if(Config -> CommandConfig -> DownloadMacro[0])
  1485.                 SerialCommand(Config -> CommandConfig -> DownloadMacro);
  1486.         }
  1487.     }
  1488. }
  1489.  
  1490.     /* StartXprSend():
  1491.      *
  1492.      *    Send files via xpr.
  1493.      */
  1494.  
  1495. BYTE __regargs
  1496. StartXprSend(BYTE Type,BYTE WaitForIt)
  1497. {
  1498.     STRPTR    From,To,Name;
  1499.     BYTE    Mode;
  1500.  
  1501.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1502.         return(InternalASCIIUpload(NULL,WaitForIt));
  1503.  
  1504.     switch(Type)
  1505.     {
  1506.         case TRANSFER_BINARY:
  1507.  
  1508.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  1509.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  1510.             From    = Config -> PathConfig -> BinaryUploadPath;
  1511.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1512.             break;
  1513.  
  1514.         case TRANSFER_TEXT:
  1515.  
  1516.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  1517.             Mode    = Config -> TransferConfig -> TextUploadType;
  1518.             From    = Config -> PathConfig -> TextUploadPath;
  1519.             To    = Config -> PathConfig -> TextDownloadPath;
  1520.             break;
  1521.  
  1522.         case TRANSFER_ASCII:
  1523.  
  1524.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1525.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1526.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1527.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1528.             break;
  1529.     }
  1530.  
  1531.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1532.     {
  1533.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1534.         Mode    = XFER_EXTERNALPROGRAM;
  1535.     }
  1536.  
  1537.     if(Mode == XFER_EXTERNALPROGRAM)
  1538.     {
  1539.         STRPTR    String;
  1540.         LONG    Error;
  1541.         BYTE    Result;
  1542.  
  1543.         BlockWindows();
  1544.  
  1545.         if(String = BuildString(Name,From,To,Type,FALSE,NULL,NULL,&Error))
  1546.         {
  1547.             ClearSerial();
  1548.  
  1549.             if(LaunchCommand(String))
  1550.                 Result = FALSE;
  1551.             else
  1552.                 Result = TRUE;
  1553.  
  1554.             RestartSerial(TRUE);
  1555.  
  1556.             FreeVecPooled(String);
  1557.         }
  1558.         else
  1559.             Result = FALSE;
  1560.  
  1561.         ReleaseWindows();
  1562.  
  1563.         return(Result);
  1564.     }
  1565.     else
  1566.     {
  1567.         struct FileRequester    *FileRequest;
  1568.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  1569.         BYTE             OldStatus = Status;
  1570.         STRPTR             UploadPath;
  1571.         BYTE             DidSend = TRUE;
  1572.         BPTR             NewDir,OldDir;
  1573.  
  1574.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1575.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1576.  
  1577.             /* We are uploading data. */
  1578.  
  1579.         Uploading = TRUE;
  1580.  
  1581.             /* Select the upload path. */
  1582.  
  1583.         switch(Type)
  1584.         {
  1585.             case TRANSFER_BINARY:
  1586.  
  1587.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  1588.                 break;
  1589.  
  1590.             case TRANSFER_TEXT:
  1591.  
  1592.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  1593.                 break;
  1594.  
  1595.             case TRANSFER_ASCII:
  1596.  
  1597.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  1598.                 break;
  1599.         }
  1600.  
  1601.         if(UploadPath[0])
  1602.         {
  1603.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  1604.                 OldDir = CurrentDir(NewDir);
  1605.             else
  1606.                 OldDir = NULL;
  1607.         }
  1608.         else
  1609.             NewDir = OldDir = NULL;
  1610.  
  1611.         BlockWindows();
  1612.  
  1613.             /* If not initialized, try to set up a new
  1614.              * external transfer protocol.
  1615.              */
  1616.  
  1617.         if(!XProtocolBase)
  1618.         {
  1619.             if(SelectProtocol(LastXprLibrary,Window))
  1620.             {
  1621.                 if(ProtocolSetup(FALSE))
  1622.                 {
  1623.                     SaveProtocolOpts();
  1624.  
  1625.                     strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  1626.                 }
  1627.             }
  1628.         }
  1629.  
  1630.         if(XProtocolBase)
  1631.         {
  1632.             SetTransferMenu(TRUE);
  1633.  
  1634.                 /* Do we need to use our own file requester or
  1635.                  * will xpr handle this job for us?
  1636.                  */
  1637.  
  1638.             if(TransferBits & XPRS_NOSNDREQ)
  1639.             {
  1640.                     /* Open the transfer info window. */
  1641.  
  1642.                 if(TransferPanel(SendQuery[Type]))
  1643.                 {
  1644.                     Status = STATUS_UPLOAD;
  1645.  
  1646.                         /* Shut up the serial line. */
  1647.  
  1648.                     ClearSerial();
  1649.  
  1650.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1651.  
  1652.                         /* Perform upload. */
  1653.  
  1654.                     if(ReadRequest && WriteRequest)
  1655.                     {
  1656.                         if(XProtocolSend(XprIO))
  1657.                             TransferFailed = FALSE;
  1658.                         else
  1659.                             TransferFailed = TRUE;
  1660.                     }
  1661.                     else
  1662.                         TransferFailed = TRUE;
  1663.  
  1664.                     if(TransferFailed || TransferAborted)
  1665.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1666.                     else
  1667.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1668.  
  1669.                     if(TransferFailed || TransferError)
  1670.                     {
  1671.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1672.                             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1673.  
  1674.                         DeleteTransferPanel(WaitForIt);
  1675.                     }
  1676.                     else
  1677.                     {
  1678.                         if(TransferWindow)
  1679.                         {
  1680.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1681.                                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1682.  
  1683.                             WaitTime(2,0);
  1684.                         }
  1685.  
  1686.                         DeleteTransferPanel(FALSE);
  1687.                     }
  1688.  
  1689.                     Status = OldStatus;
  1690.  
  1691.                         /* And request another character. */
  1692.  
  1693.                     RestartSerial(FALSE);
  1694.                 }
  1695.             }
  1696.             else
  1697.             {
  1698.                     /* We will need the file requester to find
  1699.                      * out which file(s) are to be transferred.
  1700.                      * Multiple files and wildcards are
  1701.                      * supported as well as plain file names.
  1702.                      */
  1703.  
  1704.                 if(FileRequest = GetFile(Window,SendQuery[Type],UploadPath,"",DummyBuffer,"",FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),TRUE))
  1705.                 {
  1706.                     strcpy(UploadPath,FileRequest -> rf_Dir);
  1707.  
  1708.                     ConfigChanged = TRUE;
  1709.  
  1710.                     if(FileTransferInfo = BuildFileTransferInfo(FileRequest))
  1711.                     {
  1712.                             /* Make sure that at least the
  1713.                              * first file gets transferred
  1714.                              * in case the protocol does
  1715.                              * no support batch upload.
  1716.                              */
  1717.  
  1718.                         XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  1719.  
  1720.                         if(TransferPanel(SendQuery[Type]))
  1721.                         {
  1722.                             Status = STATUS_UPLOAD;
  1723.  
  1724.                             ClearSerial();
  1725.  
  1726.                             LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1727.  
  1728.                             if(ReadRequest && WriteRequest)
  1729.                             {
  1730.                                 if(XProtocolSend(XprIO))
  1731.                                     TransferFailed = FALSE;
  1732.                                 else
  1733.                                     TransferFailed = TRUE;
  1734.                             }
  1735.                             else
  1736.                                 TransferFailed = TRUE;
  1737.  
  1738.                             if(TransferFailed || TransferAborted)
  1739.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1740.                             else
  1741.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1742.  
  1743.                             if(TransferFailed || TransferError)
  1744.                             {
  1745.                                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1746.                                     WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1747.  
  1748.                                 DeleteTransferPanel(WaitForIt);
  1749.                             }
  1750.                             else
  1751.                             {
  1752.                                 if(TransferWindow)
  1753.                                 {
  1754.                                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1755.                                         WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1756.  
  1757.                                     WaitTime(2,0);
  1758.                                 }
  1759.  
  1760.                                 DeleteTransferPanel(FALSE);
  1761.                             }
  1762.  
  1763.                             Status = OldStatus;
  1764.  
  1765.                             RestartSerial(FALSE);
  1766.                         }
  1767.                         else
  1768.                             MyEasyRequest(Window,LocaleString(MSG_TERMTRANSFER_FAILED_TO_LOCATE_DIRECTORY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FileRequest -> rf_Dir);
  1769.  
  1770.                         if(FileTransferInfo)
  1771.                         {
  1772.                             FreeFileTransferInfo(FileTransferInfo);
  1773.  
  1774.                             FileTransferInfo = NULL;
  1775.                         }
  1776.                     }
  1777.  
  1778.                     FreeAslRequest(FileRequest);
  1779.                 }
  1780.                 else
  1781.                     DidSend = FALSE;
  1782.             }
  1783.         }
  1784.         else
  1785.             SetTransferMenu(FALSE);
  1786.  
  1787.         if(OldDir)
  1788.             CurrentDir(OldDir);
  1789.  
  1790.         if(NewDir)
  1791.             UnLock(NewDir);
  1792.  
  1793.         if(SendAbort && UsesZModem)
  1794.             SerWrite(ZModemCancel,20);
  1795.  
  1796.         SendAbort = FALSE;
  1797.  
  1798.         ReleaseWindows();
  1799.  
  1800.         Uploading = FALSE;
  1801.  
  1802.         if(WaitForIt)
  1803.         {
  1804.             if(Config -> CommandConfig -> UploadMacro[0])
  1805.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  1806.         }
  1807.  
  1808.         DidTransfer = FALSE;
  1809.  
  1810.         return(DidSend);
  1811.     }
  1812. }
  1813.  
  1814.     /* StartXprSendFromList():
  1815.      *
  1816.      *    Send files via xpr.
  1817.      */
  1818.  
  1819. BYTE __regargs
  1820. StartXprSendFromList(BYTE Type,BYTE WaitForIt)
  1821. {
  1822.     STRPTR    From,To,Name;
  1823.     BYTE    Mode;
  1824.  
  1825.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1826.         return(InternalASCIIUpload(NULL,WaitForIt));
  1827.  
  1828.     switch(Type)
  1829.     {
  1830.         case TRANSFER_BINARY:
  1831.  
  1832.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  1833.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  1834.             From    = Config -> PathConfig -> BinaryUploadPath;
  1835.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1836.             break;
  1837.  
  1838.         case TRANSFER_TEXT:
  1839.  
  1840.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  1841.             Mode    = Config -> TransferConfig -> TextUploadType;
  1842.             From    = Config -> PathConfig -> TextUploadPath;
  1843.             To    = Config -> PathConfig -> TextDownloadPath;
  1844.             break;
  1845.  
  1846.         case TRANSFER_ASCII:
  1847.  
  1848.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1849.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1850.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1851.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1852.             break;
  1853.     }
  1854.  
  1855.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1856.     {
  1857.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1858.         Mode    = XFER_EXTERNALPROGRAM;
  1859.     }
  1860.  
  1861.     if(Mode == XFER_EXTERNALPROGRAM)
  1862.     {
  1863.         STRPTR    String;
  1864.         LONG    Error;
  1865.         BYTE    Result;
  1866.  
  1867.         BlockWindows();
  1868.  
  1869.         if(String = BuildString(Name,From,To,Type,FALSE,NULL,FileTransferInfo,&Error))
  1870.         {
  1871.             ClearSerial();
  1872.  
  1873.             if(LaunchCommand(String))
  1874.                 Result = FALSE;
  1875.             else
  1876.                 Result = TRUE;
  1877.  
  1878.             RestartSerial(TRUE);
  1879.  
  1880.             FreeVecPooled(String);
  1881.         }
  1882.         else
  1883.             Result = FALSE;
  1884.  
  1885.         if(FileTransferInfo)
  1886.         {
  1887.             FreeFileTransferInfo(FileTransferInfo);
  1888.  
  1889.             FileTransferInfo = NULL;
  1890.         }
  1891.  
  1892.         ReleaseWindows();
  1893.  
  1894.         return(Result);
  1895.     }
  1896.     else
  1897.     {
  1898.         BYTE    OldStatus    = Status,
  1899.             DidSend        = TRUE;
  1900.         BPTR    NewDir,
  1901.             OldDir;
  1902.         STRPTR    UploadPath;
  1903.  
  1904.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1905.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1906.  
  1907.             /* We are uploading data. */
  1908.  
  1909.         Uploading = TRUE;
  1910.  
  1911.         switch(Type)
  1912.         {
  1913.             case TRANSFER_BINARY:
  1914.  
  1915.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  1916.                 break;
  1917.  
  1918.             case TRANSFER_TEXT:
  1919.  
  1920.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  1921.                 break;
  1922.  
  1923.             case TRANSFER_ASCII:
  1924.  
  1925.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  1926.                 break;
  1927.         }
  1928.  
  1929.         if(UploadPath[0])
  1930.         {
  1931.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  1932.                 OldDir = CurrentDir(NewDir);
  1933.             else
  1934.                 OldDir = NULL;
  1935.         }
  1936.         else
  1937.             NewDir = OldDir = NULL;
  1938.  
  1939.         BlockWindows();
  1940.  
  1941.             /* If not initialized, try to set up a new
  1942.              * external transfer protocol.
  1943.              */
  1944.  
  1945.         if(!XProtocolBase)
  1946.         {
  1947.             if(WaitForIt)
  1948.             {
  1949.                 if(SelectProtocol(LastXprLibrary,Window))
  1950.                 {
  1951.                     if(ProtocolSetup(FALSE))
  1952.                     {
  1953.                         SaveProtocolOpts();
  1954.  
  1955.                         strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
  1956.                     }
  1957.                 }
  1958.             }
  1959.         }
  1960.  
  1961.         if(XProtocolBase)
  1962.         {
  1963.             SetTransferMenu(TRUE);
  1964.  
  1965.                 /* Make sure that at least the
  1966.                  * first file gets transferred
  1967.                  * in case the protocol does
  1968.                  * no support batch upload.
  1969.                  */
  1970.  
  1971.             XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  1972.  
  1973.             if(TransferPanel(SendQuery[Type]))
  1974.             {
  1975.                 Status = STATUS_UPLOAD;
  1976.  
  1977.                 ClearSerial();
  1978.  
  1979.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1980.  
  1981.                 if(ReadRequest && WriteRequest)
  1982.                 {
  1983.                     if(XProtocolSend(XprIO))
  1984.                         TransferFailed = FALSE;
  1985.                     else
  1986.                         TransferFailed = TRUE;
  1987.                 }
  1988.                 else
  1989.                     TransferFailed = TRUE;
  1990.  
  1991.                 if(TransferFailed || TransferAborted)
  1992.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1993.                 else
  1994.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1995.  
  1996.                 if(TransferFailed || TransferError)
  1997.                 {
  1998.                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1999.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2000.  
  2001.                     DeleteTransferPanel(WaitForIt);
  2002.                 }
  2003.                 else
  2004.                 {
  2005.                     if(TransferWindow)
  2006.                     {
  2007.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2008.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2009.  
  2010.                         WaitTime(2,0);
  2011.                     }
  2012.  
  2013.                     DeleteTransferPanel(FALSE);
  2014.                 }
  2015.  
  2016.                 Status = OldStatus;
  2017.  
  2018.                 RestartSerial(FALSE);
  2019.             }
  2020.  
  2021.             if(FileTransferInfo)
  2022.             {
  2023.                 FreeFileTransferInfo(FileTransferInfo);
  2024.  
  2025.                 FileTransferInfo = NULL;
  2026.             }
  2027.         }
  2028.         else
  2029.         {
  2030.             SetTransferMenu(FALSE);
  2031.  
  2032.             DidSend = FALSE;
  2033.         }
  2034.  
  2035.         if(OldDir)
  2036.             CurrentDir(OldDir);
  2037.  
  2038.         if(NewDir)
  2039.             UnLock(NewDir);
  2040.  
  2041.         if(SendAbort && UsesZModem)
  2042.             SerWrite(ZModemCancel,20);
  2043.  
  2044.         SendAbort = FALSE;
  2045.  
  2046.         ReleaseWindows();
  2047.  
  2048.         Uploading = FALSE;
  2049.  
  2050.         if(WaitForIt)
  2051.         {
  2052.             if(Config -> CommandConfig -> UploadMacro[0])
  2053.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  2054.         }
  2055.  
  2056.         DidTransfer = FALSE;
  2057.  
  2058.         return(DidSend);
  2059.     }
  2060. }
  2061.  
  2062.     /* ChangeProtocol(STRPTR ProtocolName):
  2063.      *
  2064.      *    Select a different file transfer protocol.
  2065.      */
  2066.  
  2067. BYTE __regargs
  2068. ChangeProtocol(STRPTR ProtocolName,BYTE Type)
  2069. {
  2070.     UBYTE NameBuffer[40],i;
  2071.  
  2072.     if(Type == XFER_DEFAULT)
  2073.     {
  2074.         ProtocolName = Config -> TransferConfig -> DefaultLibrary;
  2075.  
  2076.         Type = Config -> TransferConfig -> DefaultType;
  2077.     }
  2078.  
  2079.     if(Type == XFER_XPR)
  2080.     {
  2081.         if(!ProtocolName || !ProtocolName[0])
  2082.             ProtocolName = Config -> TransferConfig -> DefaultLibrary;
  2083.  
  2084.         if(!Stricmp(ProtocolName,LastXprLibrary) && XProtocolBase)
  2085.             return(TRUE);
  2086.     }
  2087.  
  2088.         /* Close the old library if still open. */
  2089.  
  2090.     if(XProtocolBase)
  2091.     {
  2092.         XProtocolCleanup(XprIO);
  2093.  
  2094.         CloseLibrary(XProtocolBase);
  2095.  
  2096.         XProtocolBase = NULL;
  2097.  
  2098.         SetTransferMenu(FALSE);
  2099.     }
  2100.  
  2101.     if(Type == XFER_INTERNAL)
  2102.     {
  2103.         UsesZModem = FALSE;
  2104.  
  2105.         SetTransferMenu(TRUE);
  2106.  
  2107.         strcpy(TransferProtocolName,"ASCII");
  2108.  
  2109.         return(TRUE);
  2110.     }
  2111.  
  2112.     if(Type == XFER_EXTERNALPROGRAM)
  2113.     {
  2114.         WORD i;
  2115.  
  2116.         memcpy(NameBuffer,FilePart(ProtocolName),40);
  2117.  
  2118.         NameBuffer[39] = 0;
  2119.  
  2120.         for(i = 0 ; i < 40 ; i++)
  2121.         {
  2122.             if(NameBuffer[i] == ' ')
  2123.             {
  2124.                 NameBuffer[i] = 0;
  2125.  
  2126.                 break;
  2127.             }
  2128.         }
  2129.  
  2130.         NameBuffer[0] = ToUpper(NameBuffer[0]);
  2131.  
  2132.         strcpy(TransferProtocolName,NameBuffer);
  2133.  
  2134.         UsesZModem = FALSE;
  2135.  
  2136.         for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2137.         {
  2138.             if(!Stricmp(&NameBuffer[i],"zmodem"))
  2139.                 UsesZModem = TRUE;
  2140.         }
  2141.  
  2142.         SetTransferMenu(TRUE);
  2143.  
  2144.         return(TRUE);
  2145.     }
  2146.  
  2147.         /* Clear the XPR interface buffer. */
  2148.  
  2149.     memset(XprIO,0,sizeof(struct XPR_IO));
  2150.  
  2151.         /* Copy the name of the library. */
  2152.  
  2153.     strcpy(NameBuffer,FilePart(ProtocolName));
  2154.  
  2155.         /* Extract the name itself (strip the `.library'). */
  2156.  
  2157.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2158.     {
  2159.         if(NameBuffer[i] == '.')
  2160.         {
  2161.             NameBuffer[i] = 0;
  2162.  
  2163.             break;
  2164.         }
  2165.     }
  2166.  
  2167.         /* Check if the transfer protocol is a sort of ZModem. */
  2168.  
  2169.     UsesZModem = FALSE;
  2170.  
  2171.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2172.     {
  2173.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  2174.             UsesZModem = TRUE;
  2175.     }
  2176.  
  2177.         /* Reset the scanner. */
  2178.  
  2179.     FlowInit(TRUE);
  2180.  
  2181.         /* Obtain the protocol default settings. */
  2182.  
  2183.     if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  2184.         ProtocolOptsBuffer[0] = 0;
  2185.  
  2186.     NameBuffer[3] = ToUpper(NameBuffer[3]);
  2187.  
  2188.         /* Initialize the interface structure. */
  2189.  
  2190.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2191.     XprIO -> xpr_fopen    = xpr_fopen;
  2192.     XprIO -> xpr_fclose    = xpr_fclose;
  2193.     XprIO -> xpr_fread    = xpr_fread;
  2194.     XprIO -> xpr_fwrite    = xpr_fwrite;
  2195.     XprIO -> xpr_sread    = xpr_sread;
  2196.     XprIO -> xpr_swrite    = xpr_swrite;
  2197.     XprIO -> xpr_sflush    = xpr_sflush;
  2198.     XprIO -> xpr_update    = xpr_update;
  2199.     XprIO -> xpr_chkabort    = xpr_chkabort;
  2200.     XprIO -> xpr_gets    = xpr_gets;
  2201.     XprIO -> xpr_setserial    = xpr_setserial;
  2202.     XprIO -> xpr_ffirst    = xpr_ffirst;
  2203.     XprIO -> xpr_fnext    = xpr_fnext;
  2204.     XprIO -> xpr_finfo    = xpr_finfo;
  2205.     XprIO -> xpr_fseek    = xpr_fseek;
  2206.     XprIO -> xpr_extension    = 4;
  2207.     XprIO -> xpr_options    = xpr_options;
  2208.     XprIO -> xpr_unlink    = xpr_unlink;
  2209.     XprIO -> xpr_squery    = xpr_squery;
  2210.     XprIO -> xpr_getptr    = xpr_getptr;
  2211.  
  2212.         /* Try to open the library. */
  2213.  
  2214.     if(XProtocolBase = (struct Library *)OpenLibrary(ProtocolName,0))
  2215.     {
  2216.             /* Set up the library. */
  2217.  
  2218.         ClearSerial();
  2219.  
  2220.         TransferBits = XProtocolSetup(XprIO);
  2221.  
  2222.         RestartSerial(FALSE);
  2223.  
  2224.         DeleteTransferPanel(TRUE);
  2225.  
  2226.             /* Successful initialization? */
  2227.  
  2228.         if(TransferBits & XPRS_SUCCESS)
  2229.         {
  2230.             SetTransferMenu(TRUE);
  2231.  
  2232.             strcpy(LastXprLibrary,ProtocolName);
  2233.  
  2234.             if(TransferBits & XPRS_HOSTMON)
  2235.                 ConTransfer = ConTransferHost;
  2236.             else
  2237.                 ConTransfer = ConProcess;
  2238.  
  2239.             if(TransferBits & XPRS_HOSTNOWAIT)
  2240.             {
  2241.                 if(!HostReadBuffer)
  2242.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  2243.             }
  2244.             else
  2245.             {
  2246.                 if(HostReadBuffer)
  2247.                 {
  2248.                     FreeVecPooled(HostReadBuffer);
  2249.  
  2250.                     HostReadBuffer = NULL;
  2251.                 }
  2252.             }
  2253.  
  2254.             strcpy(TransferProtocolName,&NameBuffer[3]);
  2255.  
  2256.             return(TRUE);
  2257.         }
  2258.         else
  2259.         {
  2260.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),ProtocolName);
  2261.  
  2262.             CloseLibrary(XProtocolBase);
  2263.  
  2264.             XProtocolBase = NULL;
  2265.  
  2266.             SetTransferMenu(FALSE);
  2267.  
  2268.             LastXprLibrary[0] = 0;
  2269.  
  2270.             TransferBits = 0;
  2271.  
  2272.             ConTransfer = ConProcess;
  2273.  
  2274.             TransferProtocolName[0] = 0;
  2275.         }
  2276.     }
  2277.     else
  2278.     {
  2279.         ConTransfer = ConProcess;
  2280.  
  2281.         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),ProtocolName);
  2282.  
  2283.         SetTransferMenu(FALSE);
  2284.  
  2285.         TransferBits = 0;
  2286.  
  2287.         LastXprLibrary[0] = 0;
  2288.  
  2289.         TransferProtocolName[0] = 0;
  2290.     }
  2291.  
  2292.     return(FALSE);
  2293. }
  2294.  
  2295.     /* ResetProtocol():
  2296.      *
  2297.      *    Return to the previously selected file
  2298.      *    transfer protocol.
  2299.      */
  2300.  
  2301. VOID
  2302. ResetProtocol()
  2303. {
  2304.     ChangeProtocol(NULL,XFER_DEFAULT);
  2305. }
  2306.  
  2307.     /* ProtocolSetup(BYTE IgnoreOptions):
  2308.      *
  2309.      *    Set up the library and options for the external protocol.
  2310.      */
  2311.  
  2312. BYTE __regargs
  2313. ProtocolSetup(BYTE IgnoreOptions)
  2314. {
  2315.     UBYTE NameBuffer[40],i;
  2316.  
  2317.         /* Close the old library if still open. */
  2318.  
  2319.     if(XProtocolBase)
  2320.     {
  2321.         XProtocolCleanup(XprIO);
  2322.  
  2323.         CloseLibrary(XProtocolBase);
  2324.  
  2325.         XProtocolBase = NULL;
  2326.  
  2327.         SetTransferMenu(FALSE);
  2328.     }
  2329.  
  2330.     if(Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  2331.     {
  2332.         if(Config -> TransferConfig -> DefaultLibrary[0])
  2333.         {
  2334.             WORD i;
  2335.  
  2336.             memcpy(NameBuffer,FilePart(Config -> TransferConfig -> DefaultLibrary),40);
  2337.  
  2338.             NameBuffer[39] = 0;
  2339.  
  2340.             for(i = 0 ; i < 40 ; i++)
  2341.             {
  2342.                 if(NameBuffer[i] == ' ')
  2343.                 {
  2344.                     NameBuffer[i] = 0;
  2345.  
  2346.                     break;
  2347.                 }
  2348.             }
  2349.  
  2350.             NameBuffer[0] = ToUpper(NameBuffer[0]);
  2351.  
  2352.             strcpy(TransferProtocolName,NameBuffer);
  2353.  
  2354.             UsesZModem = FALSE;
  2355.  
  2356.             for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2357.             {
  2358.                 if(!Stricmp(&NameBuffer[i],"zmodem"))
  2359.                     UsesZModem = TRUE;
  2360.             }
  2361.  
  2362.             SetTransferMenu(TRUE);
  2363.  
  2364.             return(TRUE);
  2365.         }
  2366.         else
  2367.             return(FALSE);
  2368.     }
  2369.  
  2370.         /* Clear the XPR interface buffer. */
  2371.  
  2372.     memset(XprIO,0,sizeof(struct XPR_IO));
  2373.  
  2374.         /* Copy the name of the library. */
  2375.  
  2376.     strcpy(NameBuffer,FilePart(LastXprLibrary));
  2377.  
  2378.         /* Extract the name itself (strip the `.library'). */
  2379.  
  2380.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2381.     {
  2382.         if(NameBuffer[i] == '.')
  2383.         {
  2384.             NameBuffer[i] = 0;
  2385.             break;
  2386.         }
  2387.     }
  2388.  
  2389.         /* Check if the transfer protocol is a sort of ZModem. */
  2390.  
  2391.     UsesZModem = FALSE;
  2392.  
  2393.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2394.     {
  2395.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  2396.             UsesZModem = TRUE;
  2397.     }
  2398.  
  2399.     NameBuffer[3] = ToUpper(NameBuffer[3]);
  2400.  
  2401.         /* Reset the scanner. */
  2402.  
  2403.     FlowInit(TRUE);
  2404.  
  2405.         /* Obtain the protocol default settings. */
  2406.  
  2407.     if(!IgnoreOptions)
  2408.     {
  2409.         if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  2410.             ProtocolOptsBuffer[0] = 0;
  2411.     }
  2412.  
  2413.         /* Initialize the interface structure. */
  2414.  
  2415.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2416.     XprIO -> xpr_fopen    = xpr_fopen;
  2417.     XprIO -> xpr_fclose    = xpr_fclose;
  2418.     XprIO -> xpr_fread    = xpr_fread;
  2419.     XprIO -> xpr_fwrite    = xpr_fwrite;
  2420.     XprIO -> xpr_sread    = xpr_sread;
  2421.     XprIO -> xpr_swrite    = xpr_swrite;
  2422.     XprIO -> xpr_sflush    = xpr_sflush;
  2423.     XprIO -> xpr_update    = xpr_update;
  2424.     XprIO -> xpr_chkabort    = xpr_chkabort;
  2425.     XprIO -> xpr_gets    = xpr_gets;
  2426.     XprIO -> xpr_setserial    = xpr_setserial;
  2427.     XprIO -> xpr_ffirst    = xpr_ffirst;
  2428.     XprIO -> xpr_fnext    = xpr_fnext;
  2429.     XprIO -> xpr_finfo    = xpr_finfo;
  2430.     XprIO -> xpr_fseek    = xpr_fseek;
  2431.     XprIO -> xpr_extension    = 4;
  2432.     XprIO -> xpr_options    = xpr_options;
  2433.     XprIO -> xpr_unlink    = xpr_unlink;
  2434.     XprIO -> xpr_squery    = xpr_squery;
  2435.     XprIO -> xpr_getptr    = xpr_getptr;
  2436.  
  2437.         /* Try to open the library. */
  2438.  
  2439.     if(XProtocolBase = (struct Library *)OpenLibrary(LastXprLibrary,0))
  2440.     {
  2441.             /* Set up the library. */
  2442.  
  2443.         ClearSerial();
  2444.  
  2445.         TransferBits = XProtocolSetup(XprIO);
  2446.  
  2447.         RestartSerial(FALSE);
  2448.  
  2449.         DeleteTransferPanel(IgnoreOptions != TRUE);
  2450.  
  2451.             /* Successful initialization? */
  2452.  
  2453.         if(TransferBits & XPRS_SUCCESS)
  2454.         {
  2455.             SetTransferMenu(TRUE);
  2456.  
  2457.             if(TransferBits & XPRS_HOSTMON)
  2458.                 ConTransfer = ConTransferHost;
  2459.             else
  2460.                 ConTransfer = ConProcess;
  2461.  
  2462.             if(TransferBits & XPRS_HOSTNOWAIT)
  2463.             {
  2464.                 if(!HostReadBuffer)
  2465.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  2466.             }
  2467.             else
  2468.             {
  2469.                 if(HostReadBuffer)
  2470.                 {
  2471.                     FreeVecPooled(HostReadBuffer);
  2472.  
  2473.                     HostReadBuffer = NULL;
  2474.                 }
  2475.             }
  2476.  
  2477.             strcpy(TransferProtocolName,&NameBuffer[3]);
  2478.  
  2479.             return(TRUE);
  2480.         }
  2481.         else
  2482.         {
  2483.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  2484.  
  2485.             CloseLibrary(XProtocolBase);
  2486.  
  2487.             XProtocolBase = NULL;
  2488.  
  2489.             LastXprLibrary[0] = 0;
  2490.  
  2491.             TransferBits = 0;
  2492.  
  2493.             ConTransfer = ConProcess;
  2494.  
  2495.             SetTransferMenu(FALSE);
  2496.  
  2497.             TransferProtocolName[0] = 0;
  2498.         }
  2499.     }
  2500.     else
  2501.     {
  2502.         ConTransfer = ConProcess;
  2503.  
  2504.         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  2505.  
  2506.         LastXprLibrary[0] = 0;
  2507.  
  2508.         TransferBits = 0;
  2509.  
  2510.         SetTransferMenu(FALSE);
  2511.  
  2512.         TransferProtocolName[0] = 0;
  2513.     }
  2514.  
  2515.     return(FALSE);
  2516. }
  2517.  
  2518.     /* SaveProtocolOpts():
  2519.      *
  2520.      *    Save the current protocol settings to an environment variable.
  2521.      */
  2522.  
  2523. VOID
  2524. SaveProtocolOpts()
  2525. {
  2526.         /* It's time to save the altered options. */
  2527.  
  2528.     if(NewOptions && XProtocolBase)
  2529.     {
  2530.         UBYTE NameBuffer[40],i;
  2531.  
  2532.             /* Strip the `.library' part. */
  2533.  
  2534.         strcpy(NameBuffer,FilePart(LastXprLibrary));
  2535.  
  2536.         for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2537.         {
  2538.             if(NameBuffer[i] == '.')
  2539.             {
  2540.                 NameBuffer[i] = 0;
  2541.                 break;
  2542.             }
  2543.         }
  2544.  
  2545.             /* Cause the xpr.library to prompt for
  2546.              * input. We expect the library to fill
  2547.              * the prompt string with the default
  2548.              * settings. The resulting string is
  2549.              * intercepted by xpr_stealopts, saved
  2550.              * to an environment variable and will
  2551.              * serve as a reinitialization string
  2552.              * later.
  2553.              */
  2554.  
  2555.         XprIO -> xpr_filename    = NULL;
  2556.         XprIO -> xpr_gets    = xpr_stealopts;
  2557.         XprIO -> xpr_extension    = 0;
  2558.         XprIO -> xpr_options    = NULL;
  2559.  
  2560.         ClearSerial();
  2561.  
  2562.         XProtocolSetup(XprIO);
  2563.  
  2564.         DeleteTransferPanel(FALSE);
  2565.  
  2566.             /* Save the options in case anything goes
  2567.              * wrong.
  2568.              */
  2569.  
  2570.         NewOptions = FALSE;
  2571.  
  2572.         SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
  2573.  
  2574.             /* Reinitialize the library. */
  2575.  
  2576.         XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2577.         XprIO -> xpr_gets    = xpr_gets;
  2578.         XprIO -> xpr_extension    = 4;
  2579.         XprIO -> xpr_options    = xpr_options;
  2580.  
  2581.         XProtocolSetup(XprIO);
  2582.  
  2583.         RestartSerial(FALSE);
  2584.  
  2585.         DeleteTransferPanel(FALSE);
  2586.     }
  2587. }
  2588.  
  2589.     /* SelectProtocol(STRPTR Name,struct Window *ParentWindow):
  2590.      *
  2591.      *    Select a different transfer protocol library using
  2592.      *    the asl.library file requester.
  2593.      */
  2594.  
  2595. BYTE __regargs
  2596. SelectProtocol(STRPTR Name,struct Window *ParentWindow)
  2597. {
  2598.     strcpy(SharedBuffer,LastXprLibrary);
  2599.  
  2600.     if(PickFile(Window,"Libs:","xpr#?.library",LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),SharedBuffer,NT_LIBRARY))
  2601.     {
  2602.         if(Stricmp(SharedBuffer,LastXprLibrary))
  2603.         {
  2604.             strcpy(LastXprLibrary,SharedBuffer);
  2605.  
  2606.             return(TRUE);
  2607.         }
  2608.     }
  2609.  
  2610.     return(FALSE);
  2611. }
  2612.  
  2613.     /* TransferCleanup():
  2614.      *
  2615.      *    We did a file transfer (auto-download?) and
  2616.      *    will need to close the transfer window.
  2617.      */
  2618.  
  2619. VOID
  2620. TransferCleanup()
  2621. {
  2622.     if(DidTransfer)
  2623.     {
  2624.         if(TransferFailed || TransferError)
  2625.         {
  2626.             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2627.                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2628.  
  2629.             DeleteTransferPanel(TRUE);
  2630.         }
  2631.         else
  2632.         {
  2633.             if(TransferWindow)
  2634.             {
  2635.                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2636.                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2637.  
  2638.                 WaitTime(2,0);
  2639.             }
  2640.  
  2641.             DeleteTransferPanel(FALSE);
  2642.         }
  2643.  
  2644.         if(SendAbort && UsesZModem)
  2645.             SerWrite(ZModemCancel,20);
  2646.  
  2647.         SendAbort = FALSE;
  2648.  
  2649.         if(Config -> CommandConfig -> DownloadMacro[0])
  2650.             SerialCommand(Config -> CommandConfig -> DownloadMacro);
  2651.  
  2652.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  2653.  
  2654.         DidTransfer = FALSE;
  2655.     }
  2656.     else
  2657.     {
  2658.         if(TransferFailed || TransferError)
  2659.         {
  2660.             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2661.                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2662.  
  2663.             DeleteTransferPanel(TRUE);
  2664.         }
  2665.         else
  2666.         {
  2667.             if(TransferWindow)
  2668.             {
  2669.                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2670.                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2671.  
  2672.                 WaitTime(2,0);
  2673.             }
  2674.  
  2675.             DeleteTransferPanel(FALSE);
  2676.         }
  2677.     }
  2678.  
  2679.     BinaryTransfer = TRUE;
  2680.  
  2681.     Status = STATUS_READY;
  2682.  
  2683.     ReleaseWindows();
  2684. }
  2685.  
  2686.     /* RemoveUploadListItem(STRPTR Name):
  2687.      *
  2688.      *    Remove a named item from the upload list.
  2689.      */
  2690.  
  2691. VOID __regargs
  2692. RemoveUploadListItem(STRPTR Name)
  2693. {
  2694.     BPTR NameLock;
  2695.  
  2696.     if(NameLock = Lock(Name,ACCESS_READ))
  2697.     {
  2698.         struct GenericList    *List = GenericListTable[GLIST_UPLOAD];
  2699.         struct Node        *Node;
  2700.         STRPTR             Base = FilePart(Name);
  2701.  
  2702.         ObtainSemaphore(&List -> ListSemaphore);
  2703.  
  2704.         Node = (struct Node *)List -> ListHeader . mlh_Head;
  2705.  
  2706.         while(Node -> ln_Succ)
  2707.         {
  2708.             if(!Stricmp(Base,FilePart(Node -> ln_Name)))
  2709.             {
  2710.                 BPTR ListLock;
  2711.  
  2712.                 if(ListLock = Lock(Node -> ln_Name,ACCESS_READ))
  2713.                 {
  2714.                     if(SameLock(ListLock,NameLock) == LOCK_SAME)
  2715.                     {
  2716.                         Forbid();
  2717.  
  2718.                         ReleaseSemaphore(&List -> ListSemaphore);
  2719.  
  2720.                         DeleteGenericListNode(List,Node);
  2721.  
  2722.                         Permit();
  2723.  
  2724.                         UnLock(ListLock);
  2725.  
  2726.                         UnLock(NameLock);
  2727.  
  2728.                         return;
  2729.                     }
  2730.  
  2731.                     UnLock(ListLock);
  2732.                 }
  2733.             }
  2734.  
  2735.             Node = Node -> ln_Succ;
  2736.         }
  2737.  
  2738.         ReleaseSemaphore(&List -> ListSemaphore);
  2739.  
  2740.         UnLock(NameLock);
  2741.     }
  2742. }
  2743.